import os
import uuid
import logging
import json

from django.conf import settings
from django.db.models import Q
from django.forms.models import model_to_dict
from django.http import JsonResponse, HttpResponse
from django.utils.safestring import mark_safe
from ..utils import delete_html_tag
from django.views import View
from article_manager.models import Article as article, Comment as CommentModel, Notice
from bcm_auth.models import User

from .. import words

LOG = logging.getLogger(__name__)


class BodyMixin:
    def body_data(self, req):
        return json.loads(req.body.decode('utf8'), encoding='utf8')


class Article(View):
    def get(self, req, *args, **kwargs):
        page = int(req.GET.get('page', 1))
        category = int(req.GET.get('category', 0))
        top = req.GET.get('top', 'false')

        # 一页显示多少内容
        limit = 8

        articles = article.objects.filter(delete=False, hide=False).order_by('-update_time')
        if top == 'true':
            articles = articles.filter(top=True).order_by('-create_time')

        if category:
            articles = articles.filter(Q(category_id=category))

        data = []

        for art in articles[(page - 1) * limit:page * limit]:
            data.append(art.to_dict())
        pages = articles.count() / limit

        context = {
            'articles': data,
            'pages': pages,
        }

        return JsonResponse(context, safe=False)


class GetArticleById(View):
    def get(self, req):
        article_id = req.GET['article_id']
        art = article.objects.filter(Q(id=article_id)).first()
        resp = {'title': art.title, 'md': art.md}
        return HttpResponse(json.dumps(resp), content_type="application/json")


class Delete(GetArticleById, BodyMixin):
    def post(self, req):
        '''
        在文章详情article_list.html中删除一篇文章
        :param req:
        :return: 文章标题
        '''
        body = self.body_data(req)
        article_id = body['article_id']
        # 删除文章安全加固，文章不在作者名下,不可删除
        try:
            article.objects.get(Q(id=article_id) & Q(author_detail_id=req.user))
        except article.DoesNotExist as e:
            return JsonResponse({'error': str(e), 'message': words.Delete.MESSAGE})

        force = False if body['force'] == 'false' else True
        if force:
            article.objects.filter(Q(id=article_id)).delete()
        else:
            article.objects.filter(Q(id=article_id)).update(delete=True)
        return HttpResponse(json.dumps({}), content_type="application/json")


class Comments(View):
    def get(self, req, *args, **kwargs):
        article_id = req.GET['article_id']
        comments = CommentModel.objects.filter(Q(article_id=article_id)).order_by('-com_time')

        respone_list = []
        comments_list = []
        comments_dict = {}

        # 添加子评论列表
        for comment in comments:
            comments_list.append(comment.to_dict())

        for comment in comments_list:
            id = comment['id']
            comments_dict[id] = comment

        for comment in comments_list:
            pid = comment["farther_comment_id"]
            if pid == -1:
                respone_list.append(comment)
            else:
                comments_dict[pid]['cid'].append(comment)

        return HttpResponse(json.dumps(respone_list), content_type="application/json")

    def post(self, req, *args, **kwargs):
        resp = {'msg': 200}

        data = json.loads(req.body.decode('utf8'))

        article_id = int(data['article_id'])
        try:
            user_id = int(data['user'])
            if user_id == data.get('fid', ''):
                LOG.error('不允许自己评论自己的评论')
                resp['msg'] = 500
                return JsonResponse(resp)
        except ValueError:
            user_id = 1
            raise Exception

        try:
            content = data['content']
            if not content:
                resp['msg'] = 500
                return JsonResponse(resp)
        except KeyError:
            resp['msg'] = 500
            return JsonResponse(resp)

        fid = data.get('fid', -1)

        # 预防输入框脚本攻击
        content = delete_html_tag(content)

        if fid == -1:
            CommentModel.objects.create(article_id=article_id, user_id=user_id, content=content)
            return JsonResponse(resp)

        CommentModel.objects.create(article_id=article_id, user_id=user_id, content=content, farther_comment_id=fid)
        return JsonResponse(resp)


class UserView(View):

    def get(self, req, author_name):
        try:
            users = User.objects.get(username=author_name)
        except Exception as exc:
            LOG.error('%s' % exc)
            user_resp = {'username': '不存在的用户'}
            return HttpResponse(json.dumps(user_resp), content_type="application/json")
        if req.user.id:
            user_resp = model_to_dict(users, fields=['username', 'group', 'email', 'last_login'])
            last_login_time = user_resp['last_login']
            user_resp['last_login'] = last_login_time.strftime("%Y-%m-%d %H:%M:%S")
            user_resp.update({'ad': users.ad})
            user_resp.update({'sex': users.sex})
            user_resp.update({'nick_name': users.nick_name})
            user_resp.update({'push_url': users.push_url})
        else:
            user_resp = model_to_dict(users, fields=['username', 'group', 'nick_name'])
        article_number = article.objects.filter(author_detail__username=author_name).count()

        user_resp.update({'article_number': article_number})

        return HttpResponse(json.dumps(user_resp), content_type="application/json")

    def post(self, req, author_name):
        userinfo = json.loads(req.body, encoding='utf8')
        user = User.objects.get(username=author_name)
        user.sex = userinfo['sex']
        user.email = userinfo['email']
        user.ad = userinfo['ad']
        user.nick_name = userinfo['nick_name']
        user.push_url = 'N/A'
        user.save()
        return HttpResponse(json.dumps({}), content_type="application/json")


class Upload(View):
    def post(self, req):
        LOG.info('start upload %s' % req.FILES)

        resp = {
            "code": 0,
            "msg": "",
            "data": {
                "src": "",
                "title": ""
            },
            "location": ""
        }

        resp_md = {
            "success": 0,
            "message": "上传成功",
            "url": "图片地址"
        }

        img_path = req.POST.get('imgpath', None)
        if img_path is not None:
            img_file = img_path.rsplit('/', 1)[1]
            img_file_path = os.path.join(settings.MEDIA_ROOT, img_file)
            os.remove(img_file_path)
            resp['data']['src'] = img_path
            resp['data']['title'] = '删除图片成功'
            return HttpResponse(json.dumps(resp), content_type="application/json")

        imgs = req.FILES.getlist('file')

        for img in imgs:
            img_id = str(uuid.uuid4())
            img_format = '.' + img.name.rsplit('.', 1)[1]
            path = os.path.join(settings.MEDIA_ROOT, img_id + img_format)
            with open(path, 'wb') as pic:
                for p in img.chunks():
                    pic.write(p)
            resp['data']['src'] = settings.MEDIA_URL + img_id + img_format
            resp['location'] = settings.MEDIA_URL + img_id + img_format
            resp['data']['title'] = img_id + img.name

        return HttpResponse(json.dumps(resp), content_type="application/json")


def notice(req):
    notice = Notice.objects.first()
    context = {
        'notice': mark_safe(notice.text),
    }
    return JsonResponse(context)


article_list_data = []
article_flag_count = 1000


def article_list(request):
    global article_flag_count
    global article_list_data

    if len(article_list_data) == 0:
        articles = article.objects.values('id', 'title')
        article_list_data = list(articles)

    article_flag_count -= 1
    if article_flag_count == 0:
        article_flag_count = 1000
        article_list_data = []

    result = request.GET.get('str', "")
    result_data = []
    if not result:
        return JsonResponse({
            'data': result_data
        })
    for art in article_list_data:
        if result in art.get('title'):
            result_data.append(art)

    return JsonResponse({
        'data': result_data
    })
